package lightswitch.server.code.sqlhelper.expression.operators.relational;

import java.util.List;

import lightswitch.server.code.object.DataRow;
import lightswitch.server.code.sqlhelper.ExpressionHelper;
import lightswitch.server.code.sqlhelper.expression.BinaryExpression;
import lightswitch.server.code.sqlhelper.expression.Expression;
import lightswitch.server.code.sqlhelper.expression.NormalTable;
import lightswitch.server.code.sqlhelper.statement.select.From;
import lightswitch.server.code.util.TypeOfData;


public class AllExpression extends BinaryExpression {
	String operator = "";

	public AllExpression(Expression left, Expression right, String operator) {
		this.leftExpression = left;
		this.rightExpression = right;

	}

	public AllExpression(String left, String right, String _op, From _from) {

		leftExpression = ExpressionHelper.parseExpression(left, _from);
		rightExpression = ExpressionHelper.parseExpression(right, _from);
		operator = _op;

	}

	public String toString() {

		return "(" + leftExpression.toString() + " " + operator + " ALL "
				+ rightExpression.toString() + " )";
	}

	public Object GetValue(DataRow row, List<From> parentFromList) {
		dataType = TypeOfData.BOOLEAN;
		int countEqual = 0;
		int countGreater = 0;
		int countLess = 0;
		Object left = leftExpression.GetValue(row,parentFromList);

		Object right = rightExpression.GetValue(row,parentFromList);
		boolean res = false;

		String type1 = leftExpression.dataType;
		if (rightExpression.dataType.equals(TypeOfData.TABLE)) {
			NormalTable tb = (NormalTable) right;
			if (tb.propertyList.size() != 1)
				return null;
			else {
				String type = tb.propertyList.get(0).getTypeOfData();
				if(tb.dataRowList.size()==0)
				{
					return true;
				}
				if (type.equals(type1)) {

					for (int i = 0; i < tb.dataRowList.size(); i++) {
						switch (type) {
						case "char":
							int k = tb.dataRowList.get(i).getEntry(0)
									.getValue().toString()
									.compareTo(left.toString());
							if (k == 0)
								countEqual++;
							if (k > 0)
								countLess++;
							if (k < 0)
								countGreater++;
							break;

						case "int":
							if (Integer.parseInt(tb.dataRowList.get(i)
									.getEntry(0).getValue().toString()) == Integer
									.parseInt((left.toString()))) {
								countEqual++;
							}
							if (Integer.parseInt(tb.dataRowList.get(i)
									.getEntry(0).getValue().toString()) > Integer
									.parseInt((left.toString()))) {
								countLess++;
							}
							if (Integer.parseInt(tb.dataRowList.get(i)
									.getEntry(0).getValue().toString()) > Integer
									.parseInt((left.toString()))) {
								countGreater++;
							}

							break;
						case "float":
							if (Float.parseFloat(tb.dataRowList.get(i)
									.getEntry(0).getValue().toString()) == Float
									.parseFloat((left.toString()))) {
								countEqual++;
							}
							if (Float.parseFloat(tb.dataRowList.get(i)
									.getEntry(0).getValue().toString()) > Float
									.parseFloat((left.toString()))) {
								countLess++;
							}
							if (Float.parseFloat(tb.dataRowList.get(i)
									.getEntry(0).getValue().toString()) > Float
									.parseFloat((left.toString()))) {
								countGreater++;
							}

							break;
						case "boolean":
							boolean b = tb.dataRowList.get(i).getEntry(0)
									.getValue().equals("true") ? true : false;
							if (b == (boolean) (left)) {
								countEqual++;
							} 
							break;
						default:
							// throw exception
							break;
						}

					}
					
					switch(operator)
					{
					case "equal":
						if(countEqual== tb.dataRowList.size())
							res=true;
						else 
							res = false;
						break;
					case "greater":
						if(countGreater== tb.dataRowList.size())
							res=true;
						else 
							res = false;
						break;
					case "greaterorequal":
						if(countLess==0)
							res=true;
						else 
							res = false;
						break;
					case "less":
						
						if(countLess== tb.dataRowList.size())
							res=true;
						else 
							res = false;
						break;
					case "lessorequal":
						if(countGreater== 0)
							res=true;
						else 
							res = false;
						break;
					case "different":
						if(countEqual== 0)
							res=true;
						else 
							res = false;
						break;
					}
					
				} else {
					// throw exception: different data type
					return null;
				}
			}
		}
		return res;
	}

}
